package com.gitee.zhziyun.cnfsystem.utils.udputil;

import com.gitee.zhziyun.cnfsystem.config.IpPortConfig;

import java.net.*;
import java.nio.charset.StandardCharsets;
import java.util.UUID;

public class MulticastSender {
    // 最大UDP包大小 (MTU通常为1500，减去IP和UDP头约1472安全)
    private static final int MAX_PACKET_SIZE = 1472;
    // 头部信息长度 (用于存储分组信息)
    private static final int HEADER_SIZE = 36; // UUID(36字符) + 分隔符

    // 实际数据部分最大大小
    private static final int MAX_DATA_SIZE = MAX_PACKET_SIZE - HEADER_SIZE;

    public static void send(String message) {
        try (MulticastSocket socket = new MulticastSocket()) {
            InetAddress group = InetAddress.getByName(IpPortConfig.getMulticastIp());
            NetworkInterface networkInterface = NetworkInterface.getByInetAddress(InetAddress.getByName(IpPortConfig.getLocalIp()));
            socket.setNetworkInterface(networkInterface);

            // 生成唯一消息ID用于分组标识1
            String messageId = UUID.randomUUID().toString();
            byte[] contentBytes = message.getBytes(StandardCharsets.UTF_8);

            // 计算需要分成多少包
            int totalPackets = (int) Math.ceil((double) contentBytes.length / MAX_DATA_SIZE);

            // 分组发送
            for (int packetNum = 0; packetNum < totalPackets; packetNum++) {
                // 计算当前包的起始位置和长度
                int offset = packetNum * MAX_DATA_SIZE;
                int length = Math.min(MAX_DATA_SIZE, contentBytes.length - offset);

                // 构建分组头 (消息ID|总包数|当前包序号)
                String header = messageId + "|" + totalPackets + "|" + packetNum + "|";
                byte[] headerBytes = header.getBytes(StandardCharsets.UTF_8);

                // 创建完整数据包 (头+数据)
                byte[] packetData = new byte[headerBytes.length + length];
                System.arraycopy(headerBytes, 0, packetData, 0, headerBytes.length);
                System.arraycopy(contentBytes, offset, packetData, headerBytes.length, length);

                // 发送数据包
                DatagramPacket sendPacket = new DatagramPacket(
                        packetData, packetData.length, group, IpPortConfig.getMulticastPort());
                socket.send(sendPacket);

                // 小延迟防止丢包
                Thread.sleep(1);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}